package com.gitee.srurl.oid.store;

import com.gitee.srurl.oid.domain.OidStoreData;

/**
 * oid 数据存储
 * 使用spi方法去加载
 *
 * @author zxw
 * @date 2023/5/7 18:07
 */
public interface IOidStore {

    /**
     * 读取当前信息
     */
    OidStoreData readCurrentData(long workerId);

    /**
     * 获取下一数据 默认非批量获取 获取+1后的下一ID
     */
    default OidStoreData getNextData(long workerId) {
        return getNextData(workerId, false, 0);
    }

    /**
     * 获取下一数据
     *
     * @param workerId 机器ID
     * @param useBatch 使用批量获取
     * @param batchNum 批量数量
     */
    default OidStoreData getNextData(long workerId, boolean useBatch, int batchNum) {

        OidStoreData oidStoreData = this.readCurrentData(workerId);
        long currentSequence;
        if (oidStoreData == null) {
            currentSequence = 0L;
        } else {
            currentSequence = oidStoreData.getStoreSequence();
        }
        currentSequence = currentSequence < 0 ? 0 : currentSequence;
        long nextMaxId = this.getNextMaxId(currentSequence, useBatch, batchNum);

        oidStoreData = OidStoreData.builder()
                .storeSequence(nextMaxId)
                .workerId(workerId)
                .batchNum(batchNum)
                .build();
        // 存储
        this.saveData(workerId, oidStoreData);
        return oidStoreData;
    }

    /**
     * 保存数据
     *
     * @param workerId     机器ID
     * @param oidStoreData 写入参数
     */
    void saveData(long workerId, OidStoreData oidStoreData);

    /**
     * 获取下一最大ID
     *
     * @param currentSequence 当前ID
     * @param useBatch        是否批量 false的话batchNum只能为1
     * @param batchNum        批量数量
     * @return 下一最大ID
     */
    default long getNextMaxId(long currentSequence, boolean useBatch, int batchNum) {

        if (!useBatch) {
            batchNum = 1;
        }

        batchNum = Math.max(batchNum, 1);
        return currentSequence + batchNum;
    }

    /**
     * 存储类型
     *
     * @return 当前存储类型
     */
    String type();
}
